package problems.painteddesert;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;

import org.codehaus.janino.ClassBodyEvaluator;
import org.codehaus.janino.CompileException;
import org.codehaus.janino.Scanner;
import org.codehaus.janino.Parser.ParseException;
import org.codehaus.janino.Scanner.ScanException;

import ec.ECFitnessEvaluator;
import ec.Solution;
import ge.BNFGrammarParser;

public class AntFitnessEvaluator extends ECFitnessEvaluator {

	private static final int num_colors = 3;

	private static final int num_grains = 30;

	private static final int world_height = 10;

	private static final int world_width = 10;

	private static int num_ants = 10;

	private static int num_steps = 300;

	private static final int E = 0, B = 1, G = 2, S = 3;
	private static final int[][] initial_world = {
			{ G, E, G, E, S, B, E, G, E, E }, { E, E, B, E, E, E, E, E, B, E },
			{ S, E, E, E, E, E, E, E, S, G }, { E, E, E, E, E, S, E, B, E, E },
			{ E, B, E, E, E, E, E, S, S, E }, { E, E, E, E, E, E, E, E, E, B },
			{ E, E, E, E, E, E, B, G, G, B }, { E, E, S, E, B, E, G, E, E, E },
			{ G, E, E, E, E, S, S, E, E, E }, { E, E, E, E, E, G, E, S, B, G } };

	private static final int[][] ants_pos = { { 3, 0 }, { 7, 0 }, { 4, 2 },
			{ 8, 2 }, { 4, 4 }, { 5, 1 }, { 4, 5 }, { 5, 7 }, { 6, 8 },
			{ 6, 9 } };

	public AntFitnessEvaluator() {
		BNFGrammarParser parser = new BNFGrammarParser(new File(
				"src/problems/painteddesert/grammar.txt"), "");

		System.out.println(parser);
	}

	public double getFitness(Solution solution) {
		String code = getCode(solution);

		World world = new World(initial_world);

		// add the ants to our world
		for (int i = 0; i < num_ants; i++) {
			Ant ant = null;
			try {
				ant = (Ant) ClassBodyEvaluator.createFastClassBodyEvaluator(
						new Scanner(null, new StringReader(
								"public void step() {\n" + code + "\n}")),
						Ant.class, (ClassLoader) null);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
			world.addAnt(ant);
			ant.setPos(ants_pos[i]);
		}

		// run the simulation
		for (int step = 0; step < num_steps; step++) {
			world.step();
		}

		// calculate the fitness
		double fitness = 0;
		//System.out.println(world);
		for (int y = 0; y < world.getHeight(); y++) {
			for (int x = 0; x < world.getWidth(); x++) {
				fitness -= world.getColor(x, y) * x;
			}
		}

		return fitness;
	}

	public double getMaxFitness() {
		// TODO Auto-generated method stub
		return 0;
	}
}
